from board_view import BoardView
from command import Command
from common import PlaceResult, AttackResult
from ship import Ship


class Board:
    def __init__(self):
        self.__status = [[0 for j in range(0, 9)] for i in range(0, 9)]
        self.__view = BoardView()
        self.__ships = []

    # 判断游戏是否结束
    def is_game_over(self) -> bool:
        for ship in self.get_ships():
            if ship.is_alive():
                return False
        return True

    # 判断在point位置是否有我方ship
    def exist_ship(self, point) -> bool:
        for ship in self.get_ships():
            if ship.contains_point(point):
                return True
        return False

    # 放置船只
    def place_ship(self, ship, cmd) -> PlaceResult:
        points = Command.to_points(cmd, ship.get_length())
        place_result = self.__can_place(points)
        if place_result != PlaceResult.SUCCESS:
            return place_result
        ship.set_live_points(points)
        self.__ships.append(ship)
        for point in points:
            self.get_status()[point.get_x()][point.get_y()] = 1
        self.__update_view(points, ship.get_short())
        return PlaceResult.SUCCESS

    # 更新view
    def __update_view(self, points, new_status) -> None:
        for point in points:
            self.update_point(point, new_status)

    # 更新view
    def update_point(self, point, new_status) -> None:
        self.get_view().update(point, new_status)

    # 判断在points中是否都可以放置
    def __can_place(self, points) -> PlaceResult:
        for point in points:
            if point.is_off_border():
                return PlaceResult.OFF_BORDER
            if self.get_status()[point.get_x()][point.get_y()] != 0:
                return PlaceResult.CONFLICT
        return PlaceResult.SUCCESS

    # 被攻击了point位置
    def be_attacked_at(self, point) -> (AttackResult, Ship):
        ships = self.get_ships()
        for ship in ships:
            if ship.contains_point(point):
                ship.be_attacked_at(point)
                if ship.is_alive():
                    break
                ships.remove(ship)
                if self.is_game_over():
                    return AttackResult.GAME_OVER, ship
                return AttackResult.SUNK, ship
        return AttackResult.HIT, Ship()

    # 返回可打印的board状态
    def display(self) -> str:
        return self.get_view().to_string()

    # 返回view属性
    def get_view(self) -> BoardView:
        return self.__view

    # 返回ships属性
    def get_ships(self) -> list:
        return self.__ships
    
    # 返回status属性
    def get_status(self) -> list:
        return self.__status
